package com.icw.configuration;

import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import com.icw.basis.BasePoEntity;
import com.icw.utility.IcwUtils;

public abstract class ConstSettings {

	// 16
	public static final int NARO_LENGTH = 16;

	// 32
	public static final int MINI_LENGTH = NARO_LENGTH * 2;

	// 64
	public static final int BASIC_LENGTH = NARO_LENGTH * 4;

	// 128
	public static final int SHORT_LENGTH = NARO_LENGTH * 8;

	// 255
	public static final int MEDIUM_LENGTH = NARO_LENGTH * 16 - 1;

	// 511
	public static final int LONG_LENGTH = NARO_LENGTH * 32 - 1;

	// 1023
	public static final int TEXT_LENGTH = NARO_LENGTH * 64 - 1;

	// 404 Not Found
	public static final Exception notFound = new Exception("Error: 404 Not found");

	// Not Allow
	public static final Exception NOT_ALLOW = new Exception("Operation Not Allow.");

	// No Permission
	public static final Exception NO_PERMISSION = new Exception("No Permission.");

	public static final Exception DUPLICATE_PERMISSION_DEFINITION = new Exception("Duplicate permission definition");

	// OauthFail
	public static final Exception oauthFailError = new Exception("000000");

	// User Inactive
	public static final Exception userDisactived = oauthFailError;

	// Default username
	public static final String DEFAULT_USERNAME = "admin@icw.io";

	// Default password
	public static final String DEFAULT_PASSWORD = "admin";

	// Name Of Default Role
	public static final String NAME_OF_DEFAULT_ROLE = "DEFAULT-ROLE";

	// Name Of ADMIN Role
	public static final String NAME_OF_ADMIN_ROLE = "ADMIN-ROLE";

	// Number Append Char
	public static final String NUMBER_APPEND_CHAR = "?";

	// Default ADMIN Id
	public static final String ADMIN_USER_DEFAULT_IDENTIFY = "ADMIN_USER_DEFAULT_IDENTIFY";

	// Package: BASISC
	public static final String BASISC_PACKAGE = "com.icw.basis";

	// Package: Interface module
	public static final String MODULE_INFC_PACKAGE = "com.icw.decoupling.defi.module";

	// Package: Interface module
	public static final String PROXY_INFC_PACKAGE = "com.icw.decoupling.defi.proxy";

	// Package: Module implement package
	public static final String MODULE_IMPL_PACKAGE = "com.icw.decoupling.impl.module";

	// Package: Proxy implement package
	public static final String PROXY_IMPL_PACKAGE = "com.icw.decoupling.impl.proxy";

	// Package: Entity
	public static final String RESOURCE_ENTY_PACKAGE = "com.icw.resource.*.entity";

	// Package: Module
	public static final String RESOURCE_MODULE_PACKAGE = "com.icw.resource.*.module.*";

	// Package: Properties Settings
	public static final String RESOURCE_PROPERTIES_PACKAGE = "com.icw.resource.*.properties";

	// Package: module initialization
	public static final String INITIAL_PACKAGE = "com.icw.resource.*.initialization";

	// Package: DTO Format
	public static final String DTO_FMT_PACKAGE = "com.icw.configuration.data_interchange.dtofmt";

	// Package: WEB API
	public static final String WEB_API_PACKAGE = "com.icw.configuration.web.api";

	// upper resourceName - entityClass - mapping
	public static final Map<String, Class<? extends BasePoEntity>> URsrcEntityMap = uRsrcEntityMap();

	// lower resourceName - entityClass - mapping
	public static final Map<String, Class<? extends BasePoEntity>> LRsrcEntityMap = lRsrcEntityMap();

	public static final int FIRST_ORDER = 0;

	public static final int LAST_ORDER = 99999;

	public static final String OUTEST_CUT_POINT = "execution(* " + ConstSettings.WEB_API_PACKAGE + ".*Api.*(..))";

	@SuppressWarnings("unchecked")
	private static Map<String, Class<? extends BasePoEntity>> uRsrcEntityMap() {
		Map<String, Class<? extends BasePoEntity>> rsrcEntityMap = new HashMap<>();
		IcwUtils.tryCatch(() -> {
			for (Class<?> temp : IcwUtils.getAllEntities()) {
				if (BasePoEntity.class.isAssignableFrom(temp) && !Modifier.isAbstract(temp.getModifiers())) {
					rsrcEntityMap.put(temp.getSimpleName(), (Class<? extends BasePoEntity>) temp);
				}
			}
		});
		return rsrcEntityMap;
	}

	@SuppressWarnings("unchecked")
	private static Map<String, Class<? extends BasePoEntity>> lRsrcEntityMap() {
		Map<String, Class<? extends BasePoEntity>> rsrcEntityMap = new HashMap<>();
		IcwUtils.tryCatch(() -> {
			for (Class<?> temp : IcwUtils.getAllEntities()) {
				if (BasePoEntity.class.isAssignableFrom(temp) && !Modifier.isAbstract(temp.getModifiers())) {
					rsrcEntityMap.put(IcwUtils.toFirstLowerCase(temp.getSimpleName()), (Class<? extends BasePoEntity>) temp);
				}
			}
		});
		return rsrcEntityMap;
	}
}
